package com.lyy.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lyy.Vo.MenuNodeVO;
import com.lyy.Vo.UserKeyWord;
import com.lyy.auth.MenuTreeBuilder;
import com.lyy.handler.BusinessException;
import com.lyy.response.ResultCode;
import com.lyy.system.entity.Menu;
import com.lyy.system.entity.Role;
import com.lyy.system.enums.MenuConverter;
import com.lyy.system.mapper.MenuMapper;
import com.lyy.system.service.MenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.ref.WeakReference;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {

    @Autowired
    private MenuMapper menuMapper;

    @Override
    public List<MenuNodeVO> queryMenuList(UserKeyWord userKeyWord) {
        QueryWrapper<Menu> wrapper=new QueryWrapper<>();
        if (userKeyWord.getType()==null || userKeyWord.getType()==""){
            wrapper.like("menu_name",userKeyWord.getKeyWord()).eq("available",1);
        }else {
            wrapper.like("menu_name",userKeyWord.getKeyWord()).eq("available",1).eq("type",userKeyWord.getType());
        }
        List<Menu> menuList=this.baseMapper.queryMenuList(wrapper);
        List<MenuNodeVO> menuNodeVOS = MenuConverter.converterToMenuNodeVO(menuList);
        return MenuTreeBuilder.build(menuNodeVOS);
    }

    @Override
    public Set<Long> getMenuByRoleId(QueryWrapper<Menu> wrapper) {
        List<Menu> menuList =  this.baseMapper.getMenuByRoleId(wrapper);
        List<MenuNodeVO> menuNodeVOS = MenuConverter.converterToMenuNodeVO(menuList);
        List<MenuNodeVO> menuNodeVOList= MenuTreeBuilder.build(menuNodeVOS);
        Set<Long> menuIds=new HashSet<>();
        getMenuIds(menuIds,menuNodeVOList);
        return menuIds;
    }

    @Override
    public Menu edit(Long id) {
        Menu menu =this.baseMapper.selectById(id);
        return menu;
    }

    @Override
    public void addMenu(Menu menu) {
        //判断父级菜单是否存在
        Long parentId =menu.getParentId();
        if (parentId !=0){  //parentId 为新增根节点
            QueryWrapper<Menu> wrapper =new QueryWrapper<>();
            wrapper.eq("id",parentId);
            Integer count =this.baseMapper.selectCount(wrapper);
            if (count == 0){
                throw new BusinessException(ResultCode.MENUPARENTNAME_NOT_EXIST.getCode(),
                        ResultCode.MENUPARENTNAME_NOT_EXIST.getMessage());
            }
        }
        QueryWrapper<Menu> wrapper1 =new QueryWrapper<>();
        wrapper1.eq("parent_id",parentId).orderByDesc("create_time").last(" limit 1");
        Menu menu1 = (Menu) this.baseMapper.selectOne(wrapper1);
        if (menu1 == null){
            menu.setOrderNum(Long.valueOf(1));
        }else {
            menu.setOrderNum(Long.valueOf(menu1.getOrderNum())+1);
        }
        this.baseMapper.insert(menu);
    }

    @Override
    public void updateMenu(Menu menu) {
        //判断父级菜单是否存在
        Long parentId =menu.getParentId();
        if (parentId !=0){
            QueryWrapper<Menu> wrapper =new QueryWrapper<>();
            wrapper.eq("id",parentId);
            Integer count =this.baseMapper.selectCount(wrapper);
            if (count == 0){
                throw new BusinessException(ResultCode.MENUPARENTNAME_NOT_EXIST.getCode(),
                        ResultCode.MENUPARENTNAME_NOT_EXIST.getMessage());
            }
        }
        this.baseMapper.updateById(menu);
    }

    @Override
    public void deleteMenu(Long id) {
        Menu menu =new Menu();
        menu.setAvailable(0);
        menu.setModifiedTime(new Date());
        QueryWrapper<Menu> wrapper=new QueryWrapper<>();
        wrapper.eq("id",id);
        this.baseMapper.update(menu,wrapper);
    }

    //取tree结构的根节点id(即没有children的节点)
    private Set<Long> getMenuIds(Set<Long> menuIds, List<MenuNodeVO> menuNodeVOList){
        for (int i = 0; i < menuNodeVOList.size(); i++) {
            if (menuNodeVOList.get(i).getChildren().size()==0){
                menuIds.add(menuNodeVOList.get(i).getId());
            }else {
                getMenuIds(menuIds,menuNodeVOList.get(i).getChildren());
            }
        }
        return menuIds;
    }

}
